from paddleocr import PaddleOCR
import cv2
import numpy as np
import os
import requests
from PIL import Image
import io
import tempfile
from pdf2image import convert_from_path
import shutil
# 导入所需库
import os
import re
import cv2
import numpy as np
from paddleocr import PaddleOCR
from pdf2image import convert_from_path
import shutil
import paddle
import requests
from PIL import Image
import io
from fastapi import APIRouter, UploadFile, File, Form, HTTPException
from fastapi.responses import JSONResponse
import json
from typing import Optional
import uuid
# 导入配置
from config import Config

# 创建路由对象

def check_paddle():
    """检查paddle-gpu的可用性；"""
    print(paddle.utils.run_check())

def remove_watermark_basic(image):
    """
    基本的去水印处理 - 使用自适应阈值和形态学操作
    
    参数:
        image: 输入图像（PIL Image对象）
    返回:
        处理后的图像（OpenCV格式）
    """
    # 将PIL图像转换为OpenCV格式
    img = np.array(image)
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    
    # 转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 自适应阈值处理，增强文本与背景对比度
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                                  cv2.THRESH_BINARY, 11, 2)
    
    # 中值滤波去除噪点
    median = cv2.medianBlur(thresh, 3)
    
    # 形态学操作，进一步去除水印
    kernel = np.ones((1, 1), np.uint8)
    opening = cv2.morphologyEx(median, cv2.MORPH_OPEN, kernel, iterations=1)
    
    # 二值化处理，使文本更清晰
    _, binary = cv2.threshold(opening, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    
    return binary

def remove_watermark_advanced(image):
    """
    高级去水印处理 - 使用多种滤波和增强技术
    
    参数:
        image: 输入图像（PIL Image对象）
    返回:
        处理后的图像（OpenCV格式）
    """
    # 将PIL图像转换为OpenCV格式
    img = np.array(image)
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    
    # 转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 提高对比度
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    enhanced = clahe.apply(gray)
    
    # 高斯模糊减少噪声
    blurred = cv2.GaussianBlur(enhanced, (3, 3), 0)
    
    # 锐化图像，增强文本边缘
    kernel = np.array([[-1, -1, -1],
                       [-1,  9, -1],
                       [-1, -1, -1]])
    sharpened = cv2.filter2D(blurred, -1, kernel)
    
    # 二值化处理
    _, binary = cv2.threshold(sharpened, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    
    # 形态学操作，进一步清理图像
    kernel = np.ones((2, 2), np.uint8)
    cleaned = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=1)
    
    return cleaned

def remove_watermark_color_filter(image):
    """
    基于颜色过滤的去水印处理 - 适用于有明显颜色差异的水印
    
    参数:
        image: 输入图像（PIL Image对象）
    返回:
        处理后的图像（OpenCV格式）
    """
    # 将PIL图像转换为OpenCV格式
    img = np.array(image)
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    
    # 转换为HSV颜色空间，便于颜色过滤
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    
    # 定义要保留的颜色范围（这里假设文本是黑色/深色）
    lower_black = np.array([0, 0, 0])
    upper_black = np.array([180, 255, 100])
    
    # 创建掩码
    mask = cv2.inRange(hsv, lower_black, upper_black)
    
    # 反转掩码以保留文本
    mask = cv2.bitwise_not(mask)
    
    # 应用掩码
    result = cv2.bitwise_and(img, img, mask=mask)
    
    # 转换为灰度图
    gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)
    
    # 二值化处理
    _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    
    return binary

def extract_text_from_pdf(pdf_path, temp_output_dir='output_files/temp', watermark_removal_method='color_filter', lang="ch")->list[str]:
    """(缺点:效果不好)(cpu调用)
    使用PaddleOCR从PDF中提取文本内容
    
    参数:
        pdf_path (str): PDF文件路径
        temp_output_dir (str): 临时图像输出目录
        watermark_removal_method (str): 去水印方法，可选 'basic', 'advanced'(高级去水印方法处理), 'color_filter'(基于颜色过滤的去水印方法), 'none'
    返回：
        包含所有页面文本的列表(第一个元素为第一页文本，第二个元素为第二页文本，以此类推)
    调用：
    # 示例用法
    pdf_path = "input_files\（第1页-4页合同）天安信通-中国银行_贷款合同.pdf"  # 替换为你的PDF文件路径
    extracted_text = extract_text_from_pdf(pdf_path, watermark_removal_method='advanced',lang="ch")
    print(extracted_text)
    
    # 打印提取结果
    for i, text in enumerate(extracted_text):
        print(f"Page {i+1}:\n{text}\n{'='*50}")
    """
    # 创建输出目录(如果不存在)
    os.makedirs(temp_output_dir, exist_ok=True)
    
    # 初始化PaddleOCR实例
    # 使用中英文预训练模型，更新参数名称
    ocr = PaddleOCR(
        use_textline_orientation=True,
        textline_orientation_model_dir=Config.TEXTLINE_ORIENTATION_MODEL_DIR,  # 使用配置文件中的模型路径
        lang=lang
    )
    
    try:
        # 将PDF转换为图像列表(每页一个图像)
        # 使用配置文件中的参数
        print(f"开始将PDF转换为图像: {pdf_path}")
        images = convert_from_path(
            pdf_path,
            dpi=Config.PDF_DPI,  # 使用配置文件中的DPI
            thread_count=Config.PDF_THREAD_COUNT,  # 使用配置文件中的线程数
            fmt='jpeg',  # 使用JPEG格式以减少内存使用
            output_folder=temp_output_dir,
            timeout=Config.PDF_TIMEOUT  # 使用配置文件中的PDF转换超时时间
        )
        print(f"PDF转换完成，共{len(images)}页")
    except Exception as e:
        print(f"转换PDF为图像时出错: {e}")
        import traceback
        traceback.print_exc()
        return []
    
    all_text = []
    
    # 定义需要过滤的文本模式
    filter_patterns = [
        r'adm\s*in',  # 匹配 "adm in" 及其变体
        r'\d{11}',    # 匹配11位数字（可能是电话号码水印）
        r'idm\s*ni',  # 其他常见水印模式
        r'dm\s*in',   # 其他常见水印模式
    ]
    
    # 遍历每一页图像
    for i, image in enumerate(images):
        try:
            print(f"处理第{i+1}页")
            # 根据选择的方法去除水印
            if watermark_removal_method == 'basic':
                processed_image = remove_watermark_basic(image)
            elif watermark_removal_method == 'advanced':
                processed_image = remove_watermark_advanced(image)
            elif watermark_removal_method == 'color_filter':
                processed_image = remove_watermark_color_filter(image)
            else:  # 'none' 或其他值，不进行预处理
                # 将PIL图像转换为OpenCV格式
                processed_image = np.array(image)
                processed_image = cv2.cvtColor(processed_image, cv2.COLOR_RGB2BGR)
            
            # 临时保存处理后的图像文件
            image_path = os.path.join(temp_output_dir, f"page_{i+1}.jpg")
            cv2.imwrite(image_path, processed_image)
            
            # 保存原始图像用于对比（可选）
            original_image_path = os.path.join(temp_output_dir, f"original_page_{i+1}.jpg")
            image.save(original_image_path, 'JPEG')
            
            # 使用PaddleOCR识别图像中的文本
            # 更新为使用predict方法，并移除不支持的cls参数
            print(f"开始OCR识别第{i+1}页")
            # 使用线程和超时处理
            import threading
            import queue
            
            def ocr_predict(q, ocr, image_path):
                try:
                    result = ocr.predict(image_path)
                    q.put(('success', result))
                except Exception as e:
                    q.put(('error', e))
            
            # 创建队列和线程
            q = queue.Queue()
            thread = threading.Thread(target=ocr_predict, args=(q, ocr, image_path))
            thread.start()
            
            # 等待结果，使用配置文件中的超时时间
            try:
                status, result = q.get(timeout=Config.OCR_PAGE_TIMEOUT)  # 使用配置文件中的每页OCR超时时间
                if status == 'error':
                    print(f"第{i+1}页OCR识别出错: {result}")
                    continue
                print(f"第{i+1}页OCR识别完成")
            except queue.Empty:
                print(f"第{i+1}页OCR识别超时（超时时间：{Config.OCR_PAGE_TIMEOUT}秒）")
                # 注意：在Windows上无法强制终止线程，但至少我们可以继续处理下一页
                continue
            
            # 处理识别结果
            page_text = []
            if result is not None:
                # 新版本 PaddleOCR 的返回结果处理
                try:
                    # 根据提供的信息，文本内容位于 result[0]['rec_texts']
                    if isinstance(result, list) and len(result) > 0 and isinstance(result[0], dict) and 'rec_texts' in result[0]:
                        texts = result[0]['rec_texts']
                        for text in texts:
                            # 过滤无关文本
                            should_filter = False
                            for pattern in filter_patterns:
                                if re.search(pattern, text, re.IGNORECASE):
                                    should_filter = True
                                    break
                            
                            # 如果文本不应被过滤且不是纯数字，则添加到结果中
                            if not should_filter and not (text.strip().isdigit() and len(text.strip()) < 3):
                                # 检查是否已经存在相同或相似的文本
                                if text not in page_text:
                                    page_text.append(text)
                    else:
                        print(f"警告：无法识别的结果格式。结果类型: {type(result)}")
                        if isinstance(result, list) and len(result) > 0:
                            print(f"第一个元素类型: {type(result[0])}")
                            if isinstance(result[0], dict):
                                print(f"第一个元素的键: {list(result[0].keys())}")
                except Exception as e:
                    print(f"处理OCR结果时出错: {e}")
                    print(f"结果类型: {type(result)}")
                    if isinstance(result, list) and len(result) > 0:
                        print(f"第一个元素: {result[0]}")
            
            # 将当前页文本添加到总结果中
            all_text.append("\n".join(page_text))
            
            # 删除临时图像文件
            os.remove(image_path)
            os.remove(original_image_path)  # 删除原始图像文件
        except Exception as e:
            print(f"处理第{i+1}页时出错: {e}")
            import traceback
            traceback.print_exc()
            continue
    
    # 删除临时目录
    if os.path.exists(temp_output_dir):
        shutil.rmtree(temp_output_dir)
    
    # 返回所有页面的文本列表
    return all_text

def list_to_txt(lst, file_path, separator='\n', keep_origin=True):
    """
    将列表写入文本文件
    :param lst: 要写入的列表
    :param file_path: 输出的文本文件路径
    :param separator: 列表元素分隔符，默认为换行符
    :param keep_origin: 是否保留原始格式（如保留列表的[]符号）（特点）
    """
    try:
        with open(file_path, 'w', encoding='utf-8') as f:
            if keep_origin:
                # 直接写入列表的字符串表示，保留[]符号
                f.write(str(lst))
            else:
                # 将列表元素用指定分隔符连接后写入文件
                f.write(separator.join(str(item) for item in lst))
        print(f"成功将列表写入 {file_path}")
    except Exception as e:
        print(f"写入文件时出错: {e}")

def txt_to_list(file_path, separator='\n', strip_whitespace=True, keep_origin=True):
    """
    从文本文件读取内容到列表
    :param file_path: 文本文件路径
    :param separator: 分隔符，默认为换行符
    :param strip_whitespace: 是否去除元素首尾空白字符
    :param keep_origin: 是否保留原始格式（如文件内容以[]开头结尾，则直接解析为Python列表）
    :return: 读取到的列表
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
            
            # 初始化lst变量
            lst = []
            
            if keep_origin and content.strip().startswith('[') and content.strip().endswith(']'):
                # 尝试直接解析为Python列表
                try:
                    import ast
                    lst = ast.literal_eval(content.strip())
                    if not isinstance(lst, list):
                        raise ValueError("解析结果不是列表类型")
                except Exception as e:
                    print(f"以原始格式解析失败: {e}，将使用常规方式解析")
                    keep_origin = False
            
            if not keep_origin:
                if separator == '\n':
                    # 按行分割时直接使用splitlines()更安全
                    lst = content.splitlines()
                else:
                    lst = content.split(separator)
                
                if strip_whitespace:
                    lst = [item.strip() for item in lst]
            elif not (keep_origin and content.strip().startswith('[') and content.strip().endswith(']')):
                # 如果keep_origin为True但内容不是以[]开头结尾，则使用常规方式解析
                if separator == '\n':
                    # 按行分割时直接使用splitlines()更安全
                    lst = content.splitlines()
                else:
                    lst = content.split(separator)
                
                if strip_whitespace:
                    lst = [item.strip() for item in lst]
                
        print(f"成功从 {file_path} 读取到列表")
        return lst
    except Exception as e:
        print(f"读取文件时出错: {e}")
        return []
    
def test_list_to_txt():
    # 使用示例
    my_list = ['第一行内容', '第二行内容', '第三行内容']
    list_to_txt(my_list, 'output.txt')  # 默认每行一个元素
    list_to_txt(my_list, 'output_comma.txt', separator=', ')  # 用逗号分隔
    list_to_txt(my_list, 'output_origin.txt', keep_origin=True)  # 保留原始格式



def test_txt_to_list():
    # 使用示例
    list_from_file = txt_to_list('output.txt')  # 默认按行读取
    print(list_from_file)

    comma_list = txt_to_list('output_comma.txt', separator=', ')  # 按逗号分隔读取
    print(comma_list)
    
    # 测试保留原始格式
    origin_list = txt_to_list('output_origin.txt', keep_origin=True)
    print(f"保留原始格式读取: {origin_list}")
    
    # 读取带有原始格式的示例文件
    try:
        contract_list = txt_to_list('input_files/list4page_contract.txt', keep_origin=True)
        print(f"合同文件读取结果类型: {type(contract_list)}")
        print(f"合同文件读取结果前20个字符: {str(contract_list)[:20]}")
    except Exception as e:
        print(f"读取合同文件时出错: {e}")


def paddleocrGpuImage(image_path, temp_dir='output_files/temp', lang="ch"):
    """
    使用PaddleOCR处理图片并返回识别结果
    
    参数:
        image_path (str): 图片路径或URL
        temp_dir (str): 临时文件目录
        lang (str): 识别语言，默认为中文
    
    返回:
        list: 识别结果列表，包含每页的rec_texts
    """
    # 创建临时目录
    os.makedirs(temp_dir, exist_ok=True)
    
    # 初始化PaddleOCR-# 文本检测+文本识别(默认使用PP-OCRv5_mobile_rec和PP-OCRv5_mobile_det模型)
    ocr = PaddleOCR(
        use_doc_orientation_classify=False, 
        use_doc_unwarping=False, 
        use_textline_orientation=True,
        textline_orientation_model_dir=Config.TEXTLINE_ORIENTATION_MODEL_DIR,  # 使用配置文件中的模型路径
        lang=lang
    )
    # ocr = PaddleOCR(use_doc_orientation_classify=True, use_doc_unwarping=True) # 文本图像预处理+文本检测+方向分类+文本识别
    # ocr = PaddleOCR(use_doc_orientation_classify=False, use_doc_unwarping=False) # 文本检测+文本行方向分类+文本识别
    
    # 判断输入是URL还是本地文件路径
    if image_path.startswith(('http://', 'https://')):
        # 下载图片
        try:
            response = requests.get(image_path)
            response.raise_for_status()
            image = Image.open(io.BytesIO(response.content))
        except Exception as e:
            print(f"下载图片时出错: {e}")
            return []
    else:
        # 读取本地图片
        try:
            image = Image.open(image_path)
        except Exception as e:
            print(f"读取图片时出错: {e}")
            return []
    
    # 应用去水印处理
    processed_image = remove_watermark_color_filter(image)
    
    # 保存处理后的图片
    temp_image_path = os.path.join(temp_dir, "processed_image.jpg")
    cv2.imwrite(temp_image_path, processed_image)
    
    # 使用PaddleOCR识别
    result = ocr.predict(temp_image_path)
    
    # 提取识别结果
    all_texts = []
    if result is not None:
        try:
            if isinstance(result, list) and len(result) > 0 and isinstance(result[0], dict) and 'rec_texts' in result[0]:
                all_texts = result[0]['rec_texts']
            else:
                print(f"警告：无法识别的结果格式")
        except Exception as e:
            print(f"处理OCR结果时出错: {e}")
    
    # 删除临时文件
    if os.path.exists(temp_image_path):
        os.remove(temp_image_path)
    
    return all_texts

def paddleocrGpuPdf(pdf_path, temp_dir='output_files/temp', lang="ch", use_v5_model=False):
    """
    使用PaddleOCR处理PDF文件并返回每页的识别结果
    
    参数:
        pdf_path (str): PDF文件路径或URL
        temp_dir (str): 临时文件目录
        lang (str): 识别语言，默认为中文
        use_v5_model (bool): 是否使用v5模型，默认为False
    
    返回:
        list[str]: 包含每页识别结果的列表，每页是一个rec_texts列表,
    """
    # 创建临时目录
    os.makedirs(temp_dir, exist_ok=True)
    
    # 初始化OCR模型
    print(f"开始初始化OCR模型，use_v5_model={use_v5_model}")
    ocr = init_ocr_model(lang, use_v5_model)
    print("OCR模型初始化完成")
    print('paddle Compiled with CUDA:', paddle.is_compiled_with_cuda())
    print('paddle Current device:', paddle.get_device())
    # 临时PDF文件路径
    temp_pdf_path = os.path.join(temp_dir, "temp_pdf.pdf")
    
    # 判断输入是URL还是本地文件路径
    if pdf_path.startswith(('http://', 'https://')):
        # 下载PDF
        try:
            response = requests.get(pdf_path)
            response.raise_for_status()
            with open(temp_pdf_path, 'wb') as f:
                f.write(response.content)
            pdf_to_process = temp_pdf_path
        except Exception as e:
            print(f"下载PDF时出错: {e}")
            return []
    else:
        # 使用本地PDF
        pdf_to_process = pdf_path
    
    try:
        # 将PDF转换为图像列表(每页一个图像)
        # 使用配置文件中的参数
        print(f"开始将PDF转换为图像: {pdf_to_process}")
        images = convert_from_path(
            pdf_to_process,
            dpi=Config.PDF_DPI,  # 使用配置文件中的DPI
            thread_count=Config.PDF_THREAD_COUNT,  # 使用配置文件中的线程数
            fmt='jpeg',  # 使用JPEG格式以减少内存使用
            output_folder=temp_dir,
            paths_only=False,  # 返回图像对象而不是路径
            timeout=Config.PDF_TIMEOUT  # 使用配置文件中的PDF转换超时时间
        )
        print(f"PDF转换完成，共{len(images)}页")
    except Exception as e:
        print(f"转换PDF为图像时出错: {e}")
        import traceback
        traceback.print_exc()
        if os.path.exists(temp_pdf_path):
            os.remove(temp_pdf_path)
        return []
    
    all_pages_text = []
    
    # 遍历每一页图像
    for i, image in enumerate(images):
        try:
            print(f"处理第{i+1}页")
            
            # 应用去水印处理
            print(f"开始去水印处理第{i+1}页")
            processed_image = remove_watermark_color_filter(image)
            print(f"完成去水印处理第{i+1}页")
            
            # 保存处理后的图像
            temp_image_path = os.path.join(temp_dir, f"page_{i+1}.jpg")
            print(f"保存处理后的图像: {temp_image_path}")
            cv2.imwrite(temp_image_path, processed_image)
            print(f"图像保存完成: {temp_image_path}")
            
            # 使用PaddleOCR识别
            print(f"开始OCR识别第{i+1}页: {temp_image_path}")
            # 使用线程和超时处理
            import threading
            import queue
            
            def ocr_predict(q, ocr, image_path):
                try:
                    print(f"线程开始处理第{i+1}页: {image_path}")
                    result = ocr.predict(image_path)
                    print(f"线程完成处理第{i+1}页: {image_path}")
                    q.put(('success', result))
                except Exception as e:
                    print(f"线程处理第{i+1}页出错: {e}")
                    q.put(('error', e))
            
            # 创建队列和线程
            q = queue.Queue()
            thread = threading.Thread(target=ocr_predict, args=(q, ocr, temp_image_path))
            thread.start()
            
            # 等待结果，使用配置文件中的超时时间
            try:
                status, result = q.get(timeout=Config.OCR_PAGE_TIMEOUT)  # 使用配置文件中的每页OCR超时时间
                if status == 'error':
                    print(f"第{i+1}页OCR识别出错: {result}")
                    continue
                print(f"第{i+1}页OCR识别完成")
            except queue.Empty:
                print(f"第{i+1}页OCR识别超时（超时时间：{Config.OCR_PAGE_TIMEOUT}秒）")
                # 注意：在Windows上无法强制终止线程，但至少我们可以继续处理下一页
                continue
            
            # 提取识别结果
            page_texts = []
            if result is not None:
                try:
                    if isinstance(result, list) and len(result) > 0 and isinstance(result[0], dict) and 'rec_texts' in result[0]:
                        page_texts = result[0]['rec_texts']
                    else:
                        print(f"警告：第{i+1}页无法识别的结果格式")
                except Exception as e:
                    print(f"处理第{i+1}页OCR结果时出错: {e}")
            page_texts = '\n'.join(str(x) for x in page_texts)  # list->str
            all_pages_text.append(page_texts)
            
            # 删除临时图像文件
            os.remove(temp_image_path)
        except Exception as e:
            print(f"处理第{i+1}页时出错: {e}")
            import traceback
            traceback.print_exc()
            continue
    
    # 删除临时PDF文件
    if os.path.exists(temp_pdf_path):
        os.remove(temp_pdf_path)
    
    return all_pages_text

def init_ocr_model(lang="ch", use_v5_model=False):
    """
    初始化PaddleOCR模型
    
    参数:
        lang (str): 识别语言，默认为中文
        use_v5_model (bool): 是否使用v5模型，默认为False
    
    返回:
        PaddleOCR: 初始化好的OCR模型
    """
    # 初始化默认参数
    ocr_params = {
        "use_doc_orientation_classify": False, 
        "use_doc_unwarping": False, 
        "use_textline_orientation": True,
        "textline_orientation_model_dir": Config.TEXTLINE_ORIENTATION_MODEL_DIR,  # 使用配置文件中的模型路径
        "lang": lang
    }
    
    # 如果需要使用v5模型，尝试加载，但捕获所有异常
    if use_v5_model:
        try:
            # 检查模型目录是否存在
            det_model_dir = Config.TEXT_DETECTION_MODEL_DIR  # 使用配置文件中的模型路径
            rec_model_dir = Config.TEXT_RECOGNITION_MODEL_DIR  # 使用配置文件中的模型路径
            
            # 检查检测模型目录是否包含实际的推理模型文件（避免只有 params/yml 而缺少 pdmodel 导致加载卡住）
            def has_model_files(model_dir: str) -> bool:
                # 常见的模型文件名：inference.pdmodel + inference.pdiparams, 或者 __model__/__params, 或 model.pdmodel
                # 也支持inference.json + inference.pdiparams的组合
                candidates = [
                    ("inference.pdmodel", "inference.pdiparams"),
                    ("__model__", "__params"),
                    ("model.pdmodel", "model.pdiparams"),
                    ("inference.json", "inference.pdiparams"),  # 添加对inference.json的支持
                ]
                for m, p in candidates:
                    if os.path.exists(os.path.join(model_dir, m)) and os.path.exists(os.path.join(model_dir, p)):
                        return True
                return False

            if os.path.exists(det_model_dir) and os.path.exists(os.path.join(det_model_dir, "inference.yml")) and has_model_files(det_model_dir):
                ocr_params["text_detection_model_dir"] = det_model_dir
                ocr_params["text_detection_model_name"] = "PP-OCRv5_server_det"
                print(f"使用检测模型: {det_model_dir}")
            else:
                print(f"检测模型目录缺失实际模型文件或配置不完整: {det_model_dir}\n  期望包含 inference.pdmodel + inference.pdiparams 或 __model__ + __params 等推理文件\n  将回退使用官方内置模型（如果可用）")

            # 检查识别模型目录（同上）
            if os.path.exists(rec_model_dir) and os.path.exists(os.path.join(rec_model_dir, "inference.yml")) and has_model_files(rec_model_dir):
                ocr_params["text_recognition_model_dir"] = rec_model_dir
                ocr_params["text_recognition_model_name"] = "PP-OCRv5_server_rec"
                print(f"使用识别模型: {rec_model_dir}")
            else:
                print(f"识别模型目录缺失实际模型文件或配置不完整: {rec_model_dir}\n  期望包含 inference.pdmodel + inference.pdiparams 或 __model__ + __params 等推理文件\n  将回退使用官方内置模型（如果可用）")
        except Exception as e:
            print(f"加载自定义模型时出错: {e}")
            print("将使用默认模型")
    
    # 初始化PaddleOCR
    try:
        print(f"开始初始化PaddleOCR，参数: {ocr_params}")
        ocr = PaddleOCR(**ocr_params)
        print("PaddleOCR初始化完成")
        # 检查模型是否正确加载
        print(f"OCR对象类型: {type(ocr)}")
        print(f"OCR对象属性: {dir(ocr)}")
        return ocr
    except Exception as e:
        print(f"初始化PaddleOCR时出错: {e}")
        import traceback
        traceback.print_exc()
        print("尝试使用最基本的参数初始化")
        # 如果出错，使用最基本的参数重试
        return PaddleOCR(lang=lang)

def test_paddleocrGpuImage():
    image_path = "input_files/1.png"
    
    # 调用函数进行OCR识别
    result = paddleocrGpuImage(image_path)
    print("图像识别结果:")
    print(result)

def test_paddleocrGpuPdf():
    pdf_path = "input_files/（第1页-4页合同）天安信通-中国银行_贷款合同.pdf"
    
    # 调用函数进行PDF OCR识别
    results = paddleocrGpuPdf(pdf_path,use_v5_model=True)
    print("results:",results)


async def process_pdf(
    file: UploadFile = File(...),
    use_v5_model: Optional[bool] = Form(Config.USE_V5_MODEL_DEFAULT),  # 使用配置文件中的默认值
    lang: Optional[str] = Form("ch")
):
    """
    处理上传的PDF文件并返回OCR识别结果
    
    参数:
        file: 上传的PDF文件
        use_v5_model: 是否使用v5模型，默认为False
        lang: 识别语言，默认为中文
    
    返回:
        JSON格式的OCR识别结果
    """
    # 检查文件类型
    if file.filename is None or not file.filename.lower().endswith('.pdf'):
        raise HTTPException(status_code=400, detail="只接受PDF文件")
    
    try:
        # 创建临时目录
        temp_dir = os.path.join(Config.TEMP_DIR, str(uuid.uuid4()))  # 使用配置文件中的临时目录
        os.makedirs(temp_dir, exist_ok=True)
        
        # 保存上传的PDF文件
        temp_pdf_path = os.path.join(temp_dir, "uploaded.pdf")
        with open(temp_pdf_path, "wb") as pdf_file:
            pdf_file.write(await file.read())
        
        # 调用OCR处理函数
        result = paddleocrGpuPdf(temp_pdf_path, temp_dir=temp_dir, lang=lang or "ch", use_v5_model=use_v5_model or Config.USE_V5_MODEL_DEFAULT)  # 使用配置文件中的默认值
        
        # 构建JSON响应
        response_data = {
            "filename": file.filename,
            "pages_count": len(result),
            "ocr_result": result
        }
        
        # 清理临时文件
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)
        
        return JSONResponse(content=response_data)
    
    except Exception as e:
        # 确保清理临时文件
        try:
            # 使用try-except确保temp_dir变量存在且不为None
            temp_dir_local = locals().get('temp_dir')
            if temp_dir_local and os.path.exists(temp_dir_local):
                shutil.rmtree(temp_dir_local)
        except:
            pass  # 忽略清理错误
        
        # 返回错误信息
        raise HTTPException(status_code=500, detail=f"处理PDF时出错: {str(e)}")
  
if __name__ == "__main__":
    # # 测试图像OCR
    # test_paddleocrGpuImage()
    
    # 测试PDF OCR
    test_paddleocrGpuPdf()